package com.systop.common.modules.security.user.webapp;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.struts2.interceptor.validation.SkipValidation;
import org.hibernate.criterion.MatchMode;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.util.Assert;

import com.opensymphony.xwork2.validator.annotations.RequiredStringValidator;
import com.opensymphony.xwork2.validator.annotations.StringLengthFieldValidator;
import com.opensymphony.xwork2.validator.annotations.Validations;
import com.systop.common.modules.dept.model.Dept;
import com.systop.common.modules.security.user.UserConstants;
import com.systop.common.modules.security.user.model.User;
import com.systop.common.modules.security.user.service.UserManager;
import com.systop.core.ApplicationException;
import com.systop.core.Constants;
import com.systop.core.dao.support.Page;
import com.systop.core.util.PageUtil;
import com.systop.core.util.RequestUtil;
import com.systop.core.webapp.struts2.action.ExtJsCrudAction;

/**
 * User对象的struts2 action。
 * 
 * @author Sam Lee,Nice
 */
@SuppressWarnings({ "serial", "rawtypes" })
@Controller
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public class UserAction extends ExtJsCrudAction<User, UserManager> {

	/** 修改密码的时候对应输入的旧密码 */
	private String oldPassword;

	/**
	 * 标识是否是用户自行修改个人信息,如果为[null]则表示 由管理员修改.否则,表示由用户自己修改
	 */
	private String selfEdit;

	/** 检测用户返回的结果 */
	private Map<String, Object> checkResult;

	/** 保存用户树形列表 */
	private List<Map> userTree;

	/** 上级部门ID，用于列出树形列表 */
	private Integer parentDeptId;

	/** 角色名称，用于员工选择器 */
	private String roleName;

	/** 以下是登录历史记录查询所需定义的 */
	private String loginUsername;

	private Date startDate;

	private Date endDate;

	/**
	 * 用户管理列表
	 */
	public String index() {
		loadModel();
		page = PageUtil.getPage(getPageNo(), getPageSize());
		// 存放查询参数
		List<Object> args = new ArrayList<Object>();
		StringBuffer hql = new StringBuffer("from User u where u.isSys is null and u.status = ?");
		args.add(getModel().getStatus());
		if (StringUtils.isNotBlank(getModel().getName())) {// 根据名称查询
			hql.append(" and u.name like ?");
			args.add(MatchMode.ANYWHERE.toMatchString(getModel().getName()));
		}
		if (StringUtils.isNotBlank(getModel().getLoginId())) {// 根据LoginId查询
			hql.append(" and u.loginId like ?");
			args.add(MatchMode.ANYWHERE.toMatchString(getModel().getLoginId()));
		}
		hql.append(" order by u.createTime desc");
		page = getManager().pageQuery(page, hql.toString(), args.toArray());
		restorePageData(page);
		return INDEX;
	}

	/** 对model进行 判断，进行非空处理 */
	private void loadModel() {
		if (getModel() == null) {
			setModel(new User());
		}
		if (StringUtils.isBlank(getModel().getStatus())) {// 默认查询正常用户[已启用]
			getModel().setStatus(UserConstants.USER_STATUS_USABLE);
		}
	}
	
	/**
	 * 用户选择列表
	 * @return
	 */
	public String selectUserIndex(){
		List<Object> args = new ArrayList<Object>();
		StringBuffer hql = new StringBuffer("from User u where u.isSys is null and u.status = ?");
		args.add(UserConstants.USER_STATUS_USABLE);
		if (getModel().getDept() != null && getModel().getDept().getId() != null) {// 根据部门查询
			hql.append(" and u.dept.id = ?");
			args.add(getModel().getDept().getId());
		}
		if (StringUtils.isNotBlank(getModel().getName())) {// 根据名称查询
			hql.append(" and u.name like ?");
			args.add(MatchMode.ANYWHERE.toMatchString(getModel().getName()));
		}
		hql.append(" order by u.createTime desc");
		page = PageUtil.getPage(getPageNo(), getPageSize());
		page = getManager().pageQuery(page, hql.toString(), args.toArray());
		restorePageData(page);
		return "select_user";
	}

	/** 编辑用户 */
	public String edit() {
		if (getModel().getId() == null) {
			getModel().setSex(UserConstants.GENT);
			getModel().setType(Constants.NO);
		}
		return INPUT;
	}

	@Validations(requiredStrings = {
			@RequiredStringValidator(fieldName = "model.loginId", message = "登录名是必须的."),
			@RequiredStringValidator(fieldName = "model.password", message = "密码是必须的.") }, stringLengthFields = { @StringLengthFieldValidator(fieldName = "password", maxLength = "32", message = "密码应少于32字符", trim = true) })
	@Override
	public String save() {
		Assert.notNull(getModel());
		try {
			if (parentDeptId == null || parentDeptId == 0) {
				addActionMessage("请选择所属部门");
				return INPUT;
			}
			getManager().save(getModel(), parentDeptId);
			if (isSelfEdit()) {
				addActionMessage("用户信息已经成功修改。");
				return INPUT;
			}
		} catch (ApplicationException e) {
			addActionError(e.getMessage());
			return INPUT;
		}
		return SUCCESS;

	}

	/** 删除用户、禁用用户 */
	public String remove() {
		super.remove();
		return SUCCESS;
	}

	/** 修改密码 */
	public String changePassword() {
		if (StringUtils.isBlank(oldPassword) || getModel() == null
				|| getModel().getId() == null) {
			return "changePassword";
		}
		String pwdToShow = getModel().getPassword();
		try {
			getManager().changePassword(getModel(), oldPassword);
			addActionMessage("修改密码成功，新密码是：" + pwdToShow);
		} catch (ApplicationException e) {
			addActionError(e.getMessage());
		}
		return "changePassword";
	}

	/** 启用用户 */
	public String unsealUser() {
		if (ArrayUtils.isEmpty(selectedItems)) {
			if (getModel() != null) {
				Serializable id = extractId(getModel());
				if (id != null) {
					selectedItems = new Serializable[] { id };
				}
			}
		}
		if (selectedItems != null) {
			for (Serializable id : selectedItems) {
				if (id != null) {
					User user = getManager().get(convertId(id));
					if (user != null) {
						getManager().unsealUser(user);
					} else {
						logger.debug("用户信息不存在.");
					}
				}
			}
			logger.debug("{} items usable user.", selectedItems.length);
		}
		return SUCCESS;
	}

	/**
	 * Build a tree as JSON format.
	 */
	@SkipValidation
	public String userTree() {
		if (RequestUtil.isJsonRequest(getRequest())) {
			Dept parent = null;
			if (parentDeptId != null) {
				parent = getManager().getDao().get(Dept.class, parentDeptId);
			} else {
				parent = (Dept) getManager().getDao().findObject(
						"from Dept d where d.parent is null");
			}
			Map<String, Object> parentMap = null;
			if (parent != null) {
				parentMap = new HashMap<String, Object>();
				parentMap.put("id", parent.getId());
				parentMap.put("text", parent.getName());
				parentMap.put("type", parent.getType());
			}
			return "tree";
		}
		return INDEX;
	}

	/**
	 * 用户登录历史记录查询
	 */
	public String userHistoryList() {
		Page page = PageUtil.getPage(getPageNo(), getPageSize());
		// 存放查询参数
		List<Object> args = new ArrayList<Object>();
		StringBuffer hql = new StringBuffer(
				"from UserLoginHistory ulh where ulh.user.loginId <> 'admin' ");
		if (StringUtils.isNotBlank(loginUsername)) {// 根据名称查询
			hql.append(" and ulh.user.name like ?");
			args.add(MatchMode.ANYWHERE.toMatchString(loginUsername));
		}

		if (startDate != null) {
			hql.append(" and ulh.loginTime >= ?");
			args.add(startDate);
		}
		if (endDate != null) {
			hql.append(" and ulh.loginTime <= ?");
			args.add(endDate);
		}

		hql.append(" order by ulh.loginTime desc");
		page = getManager().pageQuery(page, hql.toString(), args.toArray());
		restorePageData(page);
		return "userHistoryList";
	}

	/**
	 * AJAX请求，检测登录名是否已存在
	 */
	public String checkName() {
		checkResult = new HashMap<String, Object>();
		checkResult.put("exist",
				getManager().getDao().exists(getModel(), "loginId"));
		return "jsonRst";
	}

	/**
	 * 返回性别Map
	 */
	public Map<String, String> getSexMap() {
		return UserConstants.SEX_MAP;
	}

	/**
	 * 返回用户类别
	 */
	public Map<String, String> getTypeMap() {
		return UserConstants.TYPE_MAP;
	}

	/**
	 * 是否用户自己修改信息
	 */
	private boolean isSelfEdit() {
		return StringUtils.isNotBlank(selfEdit);
	}

	public void setOldPassword(String oldPassword) {
		this.oldPassword = oldPassword;
	}

	public String getSelfEdit() {
		return selfEdit;
	}

	public void setSelfEdit(String selfEdit) {
		this.selfEdit = selfEdit;
	}

	public List<Map> getUserTree() {
		return userTree;
	}

	public void setUserTree(List<Map> userTree) {
		this.userTree = userTree;
	}

	public Integer getParentDeptId() {
		return parentDeptId;
	}

	public void setParentDeptId(Integer parentDeptId) {
		this.parentDeptId = parentDeptId;
	}

	public String getRoleName() {
		return roleName;
	}

	public void setRoleName(String roleName) {
		this.roleName = roleName;
	}

	public Map<String, Object> getCheckResult() {
		return checkResult;
	}

	public String getLoginUsername() {
		return loginUsername;
	}

	public void setLoginUsername(String loginUsername) {
		this.loginUsername = loginUsername;
	}

	public Date getStartDate() {
		return startDate;
	}

	public void setStartDate(Date startDate) {
		this.startDate = startDate;
	}

	public Date getEndDate() {
		return endDate;
	}

	public void setEndDate(Date endDate) {
		this.endDate = endDate;
	}
}
